package com.sqx.modules.banArea.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sqx.common.entity.WMPoint;
import com.sqx.common.utils.Result;
import com.sqx.modules.banArea.dao.BanAreaDao;
import com.sqx.modules.banArea.entity.BanArea;
import com.sqx.modules.banArea.service.IBanAreaService;
import com.sqx.modules.cityInfo.entity.CityInfo;
import com.sqx.modules.cityInfo.service.CityInfoService;
import com.sqx.modules.sys.entity.SysUserEntity;
import com.sqx.modules.sys.entity.SysUserRoleEntity;
import com.sqx.modules.sys.service.SysUserRoleService;
import com.sqx.modules.sys.service.SysUserService;
import com.sqx.modules.utils.GeoFenceUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author wuChang
 * @since 2023-08-28
 */
@Service
public class BanAreaServiceImpl extends ServiceImpl<BanAreaDao, BanArea> implements IBanAreaService {

    @Autowired
    SysUserService sysUserService;
    @Autowired
    private SysUserRoleService sysUserRoleService;
    @Autowired
    private CityInfoService cityInfoService;

    @Override
    public Result saveBanArea(BanArea banArea) {
        if (banArea.getParentId() == null) {
            banArea.setParentId(0L);
        } else {
            for (WMPoint point : banArea.getPoints()) {
                if (!isInBanArea(point, banArea.getParentId())) {
                    return Result.error("添加的一口价区域不在限制区域内");
                }
            }
        }
        if (banArea.getAreaId() == null) {
            banArea.setCreateTime(LocalDateTime.now());
            return Result.upStatus(baseMapper.insert(banArea));
        } else {
            return Result.upStatus(baseMapper.updateById(banArea));
        }
    }

    @Override
    public IPage<BanArea> getBanAreaList(Integer page, Integer limit, BanArea banArea) {
        Page<BanArea> pages;
        if (page != null && limit != null) {
            pages = new Page<>(page, limit);
        } else {
            pages = new Page<>();
            pages.setSize(-1);
        }
        return baseMapper.getBanAreaList(pages, banArea);
    }


    @Override
    public boolean isInBanArea(WMPoint point, Long parentId) {
        QueryWrapper<BanArea> wrapper = new QueryWrapper<BanArea>().eq("is_enable", 1);
        if (parentId == null) {
            wrapper.eq("parent_id", 0);
        } else {
            wrapper.eq("area_id", parentId);
        }
        List<BanArea> areaList = baseMapper.selectList(wrapper);
        for (BanArea banArea : areaList) {
            if (GeoFenceUtil.isInPolygon(point, banArea.getPoints())) {
                return true;
            }
        }
        return false;
    }


    @Override
    public BanArea getAreaByPoint(Double lng, Double lat) {
        WMPoint point = new WMPoint();
        point.setLng(lng);
        point.setLat(lat);
        List<BanArea> areaList = baseMapper.selectList(new QueryWrapper<BanArea>().eq("is_enable", 1).ne("parent_id", 0));
        for (BanArea banArea : areaList) {
            if (GeoFenceUtil.isInPolygon(point, banArea.getPoints())) {
                return banArea;
            }
        }
        return null;

    }

    @Override
    public IPage<BanArea> getBanAreaTreeList(Integer page, Integer limit, BanArea banArea) {
        Page<BanArea> pages;
        if (page != null && limit != null) {
            pages = new Page<>(page, limit);
        } else {
            pages = new Page<>();
            pages.setSize(-1);
        }
        IPage<BanArea> banAreaIPage = baseMapper.selectPage(pages, new QueryWrapper<>(banArea).eq("parent_id", 0).orderByDesc("create_time"));
        for (BanArea record : banAreaIPage.getRecords()) {
            record.setChildrenList(baseMapper.selectList(new QueryWrapper<BanArea>().eq("parent_id", record.getAreaId())));
        }
        //        banAreaIPage.setRecords(banAreaIPage.getRecords().stream()
//                .filter(e -> e.getParentId() == 0)
//                .peek((menu) -> menu.setChildrenList(getChildrenList(menu, banAreaIPage.getRecords())))
//                .collect(Collectors.toList()));

        return banAreaIPage;

    }

    @Override
    public Result updateAreaStatus(Long areaId) {
        BanArea banArea = baseMapper.selectById(areaId);
        if (banArea.getIsEnable() == 0) {
            banArea.setIsEnable(1);
        } else {
            banArea.setIsEnable(0);
        }
        return Result.upStatus(baseMapper.updateById(banArea));


    }

    @Override
    public IPage<BanArea> getBanAppAreaList(Integer page, Integer limit, BanArea banArea) {
        Page<BanArea> pages;
        if (page != null && limit != null) {
            pages = new Page<>(page, limit);
        } else {
            pages = new Page<>();
            pages.setSize(-1);
        }
        return baseMapper.getBanAppAreaList(pages, banArea);


    }

    @Override
    public Result deleteArea(Long areaId) {


        baseMapper.delete(new QueryWrapper<BanArea>().eq("parent_id", areaId));

        return Result.upStatus(baseMapper.deleteById(areaId));
    }

    //递归查找所有菜单的子菜单
    private List<BanArea> getChildrenList(BanArea root, List<BanArea> all) {
        return all.stream().filter(categoryEntity -> categoryEntity.getParentId().equals(root.getAreaId())).peek(categoryEntity -> {
            //1、找到子菜单(递归)
            categoryEntity.setChildrenList(getChildrenList(categoryEntity, all));
        }).collect(Collectors.toList());
    }
}
